package de.hska.reka.websockets.client.annotationProcessor;

import java.lang.reflect.Field;

import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.util.ReflectionUtils;
import org.springframework.util.ReflectionUtils.FieldCallback;

import de.hska.reka.websockets.annotations.WebSocket;
import de.hska.reka.websockets.client.WebSocketClientExporter;
import de.hska.reka.websockets.client.model.WebSocketController;

public class WebSocketAnnotationProcessor implements BeanPostProcessor,
		ApplicationContextAware {

	private ApplicationContext applicationContext;

	public Object postProcessAfterInitialization(final Object bean,
			final String beanName) throws BeansException {
		System.out.println("preprocessing");
		ReflectionUtils.doWithFields(bean.getClass(), new FieldCallback() {
			public void doWith(Field field) throws IllegalArgumentException,
					IllegalAccessException {
				Class<?> classOfField = field.getType();
				System.out.println("analysing field declaring class"
						+ field.getType());
				if (classOfField.isAnnotationPresent(WebSocket.class)) {
					String beanName = applicationContext.getBeanNamesForType(WebSocketClientExporter.class)[0];
					
					WebSocketController controller = new WebSocketController();
					controller.setBean(bean);
					controller.setField(field);
					WebSocketClientExporter webSocketClientExporter = (WebSocketClientExporter) applicationContext.getBean(beanName); 
					webSocketClientExporter.addProxy(controller, classOfField);
					webSocketClientExporter.setServiceUrl(classOfField.getAnnotation(WebSocket.class).url() + ":" + classOfField.getAnnotation(WebSocket.class).port());
				}
			}
		});
		return bean;
	}

	public Object postProcessBeforeInitialization(Object bean,
			final String beanName) throws BeansException {
		return bean;
	}

	public void setApplicationContext(ApplicationContext applicationContext)
			throws BeansException {
		this.applicationContext = applicationContext;
	}
}